/*
 * @Author: yangzonglong
 * @Date: 2021-05-13 11:17:43
 * @version: v1.0.0
 * @Descripttion: 全局变量
 * @LastEditors: yangzonglong
 * @LastEditTime: 2021-05-14 18:19:13
 * @Auditor: 
 */
import React, { useState, useCallback, useEffect, useContext, useRef } from 'react';
import { Input, Dropdown, Menu } from 'antd';
import { Icon } from '@library';
import FormVariable from '../formVariable/_FormVariable';
import CustVariable from '../formVariable/_CustVariable';
import context from '../context';
import { FormField, StartEventSelfProps } from './../../../interface';
import { defVars } from './../data';
import style from './../style.module.scss';

const MenuItem = Menu.Item;
const T = window.$app.t;
const EXTENSION_ELEMENTS = 'bpmn:ExtensionElements'
const HL_GLOBAL_VAR = 'huilian:GlobalVar'
const HL_VARIABLE = 'huilian:Variable'

export default () => {
  const isSync = useRef(false); // 为true时variables变化将会同步到self
  const { self, modeler } = useContext(context);
  const [variables, setVariables] = useState<FormField[]>([]);

  const [variableVisible, setVariableVisible] = useState(false);
  const hideVariable = useCallback(() => setVariableVisible(false), []);
  const showVariable = useCallback(() => setVariableVisible(true), []);

  const [custCariableVisible, setCustCariableVisible] = useState(false);
  const hideCustVariable = useCallback(() => setCustCariableVisible(false), []);
  const showCustVariable = useCallback(() => setCustCariableVisible(true), []);

  const _self = self as StartEventSelfProps;

  // 创建XMLNode节点
  const createXMLNode = useCallback((type: string) => {
    return modeler.get('moddle').create(type)
  }, [modeler]);

  useEffect(() => {
    const variables = _self.businessObject?.extensionElements?.values?.[0]?.values || [];
    setVariables(variables.map(item => {
      const copyItem = { ...item };
      delete copyItem.$type;
      return copyItem
    }));
  }, [_self]);

  useEffect(() => {
    if(!isSync.current) return;

    _self.businessObject!.extensionElements = Object.assign(createXMLNode(EXTENSION_ELEMENTS), {
      values: [
        Object.assign(createXMLNode(HL_GLOBAL_VAR), {
          values: variables.map(item => {
            return Object.assign(createXMLNode(HL_VARIABLE), item)
          })
        })
      ]
    })
  }, [variables, createXMLNode, _self]);

  const addVariables = useCallback((rows: FormField[]) => {
    const map = variables.reduce((next, cur) => {
      next[cur.fieldName] = true;
      return next;
    }, {});

    const filter = rows.filter(item => !map[item.fieldName]);
    isSync.current = true;
    setVariables(variables.concat(filter));
    setVariableVisible(false);
    setCustCariableVisible(false);
  }, [variables]);

  const removeField = useCallback((fieldName: string) => {
    isSync.current = true;
    setVariables(variables.filter(item => item.fieldName !== fieldName))
  }, [variables]);

  const action = useCallback((fieldName?: string) => {
    return (
      <>
        {fieldName && (
          <Icon onClick={() => removeField(fieldName)} className={style.variableIcon} icon='&#xe633;' />
        )}
        <Dropdown overlay={
          <Menu>
            <MenuItem onClick={showVariable}>{T('readFormVar')}</MenuItem>
            <MenuItem onClick={showCustVariable}>{T('autoAddFormVar')}</MenuItem>
          </Menu>
        }>
          <span>
            <Icon className={style.variableIcon} icon='&#xe635;' />
          </span>
        </Dropdown>
      </>
    )
  }, [showVariable, removeField, showCustVariable]);

  return (
    <ul className={style.variable}>
      {defVars.map(item => (
          <li key={item.fieldName}>
            <Input disabled value={item.fieldName} />
            <Input disabled value={item.name} />
            <Input disabled value={item.type} />
          </li>
        ))}
      {variables.length > 0 ? (
        variables.map(item => (
          <li key={item.fieldName}>
            <Input disabled value={item.fieldName} />
            <Input disabled value={item.name} />
            <Input disabled value={item.type} />
            {action(item.fieldName)}
          </li>
        ))
      ) : (
        <li>
          <Input disabled />
          <Input disabled />
          <Input disabled />
          {action()}
        </li>
      )}

      <FormVariable onOk={addVariables} onCancel={hideVariable} visible={variableVisible} />
      <CustVariable onOk={addVariables} onCancel={hideCustVariable} visible={custCariableVisible}/>
    </ul>
  )
}
